package cn.dkdoo.utils.config.transactionInfo;


import cn.dkdoo.utils.common.ThreadLocalPool;
import cn.dkdoo.utils.config.exception.DkdTransactionException;
import cn.dkdoo.utils.config.rollbackData.RollbackDataSelf;
import cn.dkdoo.utils.config.rollbackData.RollbackDataTable;
import cn.dkdoo.utils.config.rollbackData.RollbackDetail;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author nicky
 * @date 2021/5/10 下午3:29
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TransactionInfoAbstract {
    private static final Logger logger = LoggerFactory.getLogger(TransactionInfoAbstract.class);
    // key-表名/主题 val-待回滚的表/待重发的消息
    private Map<String, RollbackDataTable> datas;
    // 自定义的回滚数据
    private List<RollbackDataSelf> selfs;
    // 事物状态 1-开启 2-休眠
    private transient Integer traStatus = Constants.traStatus.open;

//    private TransactionInfoAbstract oldTransactionInfo;

    public final void addRollbackData(RollbackDataSelf rollbackDataSelf) {
        selfs = selfs == null ? new ArrayList<>() : selfs;
        selfs.add(rollbackDataSelf);
    }

    public static final void addRollbackDataStatic(RollbackDataSelf rollbackDataSelf) {
        TransactionInfoAbstract info = ThreadLocalPool.TRAINFO_MANAGER.getCur();
        if (info == null) {
            //logger.warn("当前线程未绑定事务，请检查DkdTransactionalAspect是否生效。。。");
            return;
        }
        info.addRollbackData(rollbackDataSelf);
    }

    public final void addRollbackData(String collectionName, String beanName, String dataClass, Map<String, RollbackDetail> datasCur) {
        datas = datas == null ? new HashMap<>() : datas;
        RollbackDataTable rollbackDataTable = datas.get(collectionName);//哪张表/哪个队列
        if (rollbackDataTable == null) {
            rollbackDataTable = new RollbackDataTable(beanName, dataClass);
        }
        rollbackDataTable.addOneId(datasCur);
        datas.put(collectionName, rollbackDataTable);
    }

    public static final void addRollbackDataStatic(String collectionName, String beanName, String dataClass, Map<String, RollbackDetail> datasCur) {
        if (MapUtils.isEmpty(datasCur)) {
            return;
        }
        TransactionInfoAbstract info = ThreadLocalPool.TRAINFO_MANAGER.getCur();
        if (info == null) {
            //logger.warn("当前线程未绑定事务，请检查DkdTransactionalAspect是否生效。。。");
            return;
        }

        info.addRollbackData(collectionName, beanName, dataClass, datasCur);
    }

    /**
     * mongo事物处理完成后，可以调用此方法加入es的回滚
     * @param mongoCollectionName  mongo只读表的名称
     * @param esRollbackBean    es回滚的时候调用的bean
     * esIndex   es表名，不需要存储，维护好 mongo只读表 和 es只读表直接的关系即可
     */
    public static final void addEsRollbackDataStatic(String mongoCollectionName, String esRollbackBean) {
        TransactionInfoAbstract info = ThreadLocalPool.TRAINFO_MANAGER.getCur();
        if (info == null) {
            //logger.warn("当前线程未绑定事务，请检查DkdTransactionalAspect是否生效。。。");
            return;
        }
        RollbackDataTable rollbackDataTable = info.getDatas().get(mongoCollectionName);
        if (rollbackDataTable == null) {
            throw new DkdTransactionException("没有mongo回滚列表！");
        }
        rollbackDataTable.setEsBean(esRollbackBean);
        //rollbackDataTable.setEsIndex(esIndex);
    }

    public static boolean checkIsClose() {
        TransactionInfoAbstract transactionInfoAbstract = ThreadLocalPool.TRAINFO_MANAGER.getCur();
        if (transactionInfoAbstract == null) {
            return false;
        }
        return Constants.traStatus.open != transactionInfoAbstract.getTraStatus();
    }

    public static void makeClose() {
        TransactionInfoAbstract transactionInfoAbstract = ThreadLocalPool.TRAINFO_MANAGER.getCur();
        if (transactionInfoAbstract == null) {
            return;
        }
        transactionInfoAbstract.setTraStatus(Constants.traStatus.sleep);
    }

    public static void makeOpen() {
        TransactionInfoAbstract transactionInfoAbstract = ThreadLocalPool.TRAINFO_MANAGER.getCur();
        if (transactionInfoAbstract == null) {
            return;
        }
        transactionInfoAbstract.setTraStatus(Constants.traStatus.open);
    }

//    private void bindToThread() {
//        this.oldTransactionInfo = ThreadLocalPool.TRAINFO_MANAGER.getCur();
//        // keyword->【当前事物-绑定】存入threadLocal，事务绑定当前线程
//        ThreadLocalPool.TRAINFO_MANAGER.bindToThread(this);
//    }
//
//    private void restoreThreadLocalStatus() {
//        //todo 如果是顶层事务，会是null,是否就另一种方式释放了资源
//        ThreadLocalPool.TRAINFO_MANAGER.bindToThread(this.oldTransactionInfo);
//    }

    public static class Constants {
        public static class traStatus {
            public static final int open = 1;
            public static final int sleep = 2;
        }
    }

    public String getTraNo() {
        return null;
    }

    public boolean checkIsNewTransaction() {
        return false;
    }

    public Object getConnection() {
        return null;
    }


    public final List<RollbackDataSelf> getSelfs() {
        return this.selfs;
    }

    public Map<String, RollbackDataTable> getDatas() {
        return datas;
    }

    public Integer getTraStatus() {
        return traStatus;
    }

    public void setTraStatus(Integer traStatus) {
        this.traStatus = traStatus;
    }

}
